/**
 * STM32 ECC封装层
 * ProvideClass似于STM32硬件加密的接口
 */

#include "stm32f4xx_ecc.h"
#include "ecc_impl.h"
#include <string.h>

/* ECC上下文（全局） */
static ECC_Impl_Context ecc_ctx;
static uint8_t ecc_initialized = 0;
static uint8_t ecc_key_set = 0;

/**
 * @brief InitializeECCModule
 */
HAL_StatusTypeDef ECC_Init(void)
{
    ECC_Impl_Init(&ecc_ctx);
    ecc_initialized = 1;
    ecc_key_set = 0;
    return HAL_OK;
}

/**
 * @brief SettingsECC私钥
 */
HAL_StatusTypeDef ECC_SetKey(uint8_t* key, uint32_t key_len)
{
    if (!ecc_initialized) {
        return HAL_ERROR;
    }
    
    if (key == NULL || key_len < 32) {  // P-256Require32字节私钥
        return HAL_ERROR;
    }
    
    /* Load私钥 */
    ECC_Impl_LoadKey(&ecc_ctx, key);
    
    /* Calculate公钥 */
    ECC_Impl_ComputePublicKey(&ecc_ctx);
    
    ecc_key_set = 1;
    return HAL_OK;
}

/**
 * @brief ExecuteECCCommand
 */
HAL_StatusTypeDef ECC_ProcessCommand(uint8_t cmd, 
                                     const uint8_t* input, 
                                     uint32_t input_len,
                                     uint8_t* output, 
                                     uint32_t* output_len)
{
    if (!ecc_initialized || !ecc_key_set) {
        return HAL_ERROR;
    }
    
    if (input == NULL || output == NULL || output_len == NULL) {
        return HAL_ERROR;
    }
    
    /* According toCommandExecute操作 */
    switch (cmd) {
        case ECC_CMD_ECDH:
            /* ECDH: Input=对方公钥(64字节), Output=共享Key(32字节) */
            if (input_len != 64) {
                return HAL_ERROR;
            }
            ECC_Impl_ECDH(&ecc_ctx, input, output);
            *output_len = 32;
            break;
            
        case ECC_CMD_SIGN:
            /* ECDSA签名: Input=哈希(32字节), Output=签名(64字节) */
            if (input_len != 32) {
                return HAL_ERROR;
            }
            ECC_Impl_Sign(&ecc_ctx, input, output);
            *output_len = 64;
            break;
            
        case ECC_CMD_VERIFY:
            /* ECDSAVerify: Input=公钥(64)+哈希(32)+签名(64), Output=Result(1) */
            if (input_len < 160) {
                return HAL_ERROR;
            }
            {
                const uint8_t* pubkey = input;
                const uint8_t* hash = input + 64;
                const uint8_t* signature = input + 96;
                int result = ECC_Impl_Verify(pubkey, hash, signature);
                output[0] = result ? 1 : 0;
                *output_len = 1;
            }
            break;
            
        default:
            return HAL_ERROR;
    }
    
    return HAL_OK;
}
